﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;
using SCResources.DataLayer;
using SCResources.General;
using SCResources.ImdbSerieService;
using SCResources.Interfaces;
using Serie = SCResources.General.Serie;

namespace SCResources.BusinissLayer
{
    /// <summary>
    /// manager class
    /// </summary>
    public class ScResources : IMovableSeries,ISeriesData
    {
        //new app vars
        private SeriesData seriesData;
        private FileMoving fileMoving;
        private ImdbServices imdbService;

        //old
        private IO_Series ioSeries;
        private SerieCollection serieCollection;
        private List<string> oldCoverPaths;
        private const string OLD_COVER_PATH = "oldCover.dat";
        //file moving
        

        public SerieCollection SerieCollection
        {
            get
            {
                return serieCollection;
            }
        }

        /// <summary>
        /// standaard constructor
        /// </summary>
        public ScResources()
        {
            seriesData = new SeriesData();
            fileMoving = new FileMoving(Settings.CheckInterval, this as IMovableSeries);
            imdbService = new ImdbServices();


            UpdateAirdatesAsync();

            //ioSeries = new IO_Series();
            //serieCollection = new SerieCollection();
            
            //oldCoverPaths = new List<string>();
            //serieCollection.updateAirdates();
            removeOldCovers();

            //set settings events
            //set settings events
            Settings.selectedMoveOptionChanged += new SelectedMoveOptionChanged(checkAutoMoveOptionChanged);
            
        }

        ~ScResources()
        {
            if(oldCoverPaths.Count != 0)
            {
                IO_Covers.saveOldCoversPathsFile(OLD_COVER_PATH, oldCoverPaths);
            }
        }

        #region filemoving

        public void startFilemovingTimer()
        {
            fileMoving.start();
        }

        public void pauseFilemovingTimer()
        {
            fileMoving.pause();
        }

        private void checkAutoMoveOptionChanged(AutoMoveOption selectedOption, int interval)
        {
            switch (selectedOption)
            {
                //start thread for time moving
                case AutoMoveOption.Time:
                    fileMoving.TimerInterval = interval;
                    fileMoving.start();
                    break;
                //stop thread if IS alive.
                case AutoMoveOption.Startup:
                case AutoMoveOption.Manual:
                    fileMoving.pause();
                    break;
                default: break;
            }
        }

        public void checkFiles()
        {
            fileMoving.checkFiles();
        }

        #endregion

        #region SerieData

        /// <summary>
        /// export current series to xml file
        /// </summary>
        /// <param name="file">file path *.xml</param>
        public void Export(string file)
        {
            seriesData.ExportData(file);
        }

        /// <summary>
        /// import series file
        /// </summary>
        /// <param name="file">file path *.xml</param>
        public void Import(string file)
        {
            seriesData.ImportData(file);
        }

        /// <summary>
        /// save content at default serieList path
        /// </summary>
        public void saveCurrentContent()
        {
            seriesData.writeData();
        }

        private void UpdateAirdatesAsync()
        {
            Thread updateAirdates = new Thread(UpdateAirdates);
            updateAirdates.IsBackground = true;
            updateAirdates.Name = "UpdateAirdates";
            updateAirdates.Start();
        }

        private void UpdateAirdates()
        {
            List<SerieWrapper> series = seriesData.GetAutoAirdateTrue();

            foreach (SerieWrapper serieWrapper in series)
            {
                if (serieWrapper.AirInfo != null)
                    serieWrapper.AirInfo = imdbService.GetNextAirdate(serieWrapper.ImdbId, serieWrapper.AirInfo.Season);
                else
                {
                    serieWrapper.AirInfo = imdbService.GetNextAirdate(serieWrapper.ImdbId);
                }
            }

            foreach(SerieWrapper wrapper in series)
            {
                seriesData.Update(wrapper);
            }
        }

        public void GetLastAirdateAsync(SerieWrapper serie)
        {
            Thread getLastAirdate = new Thread(delegate (object unused)
                                                   {
                                                       GetLastAirdate(serie);
                                                   });
            getLastAirdate.IsBackground = true;
            getLastAirdate.Name = "getLastAirdate";
            getLastAirdate.Start();
        }

        public void GetLastAirdate(SerieWrapper serie)
        {
            serie.AirInfo = imdbService.GetNextAirdate(serie.ImdbId);
            seriesData.Update(serie);
        }

        public List<FileMovingSerieObject> MoveableSeries()
        {
            return seriesData.MoveableSeries();
        }

        public void UpdateCover(int serieId, Image cover)
        {
            seriesData.UpdateCover(serieId, cover);
        }

        public void Update(SerieWrapper serieWrapper)
        {
            seriesData.Update(serieWrapper);
        }

        public void Remove(int id)
        {
            seriesData.Remove(id);
        }

        public SerieWrapper Get(int id)
        {
            return seriesData.Get(id);
        }

        public List<SerieWrapper> GetAll()
        {
            return seriesData.GetAll();
        }

        public SerieWrapper Add(SerieWrapper serieWrapper)
        {
            return seriesData.Add(serieWrapper);
        }

        #endregion

        #region Settings

        /// <summary>
        /// get The settings
        /// Events in the settings need to be re assigned when first deSerializing the setting
        /// </summary>
        /// <returns>Settings</returns>
        public static Settings Settings
        {
            set
            {
                IO_Settings.SetSettings(value);
                IO_Settings.writeSettings();
            }
            get
            {
                return IO_Settings.GetSettings();
            }
        }

        public void SaveSettings()
        {
            IO_Settings.writeSettings();
        }
        
        #endregion

        #region Actions

        ///// <summary>
        ///// add new serie
        ///// </summary>
        ///// <param name="titel">serie title</param>
        ///// <param name="season">serie season</param>
        ///// <param name="episode">serie episode</param>
        ///// <param name="nextAirDate">serie nextAirDate</param>
        ////todo: rewrite more efficient: use serie object instead of all parameters of the serie object
        //public void addSerie(string titel, int season, int episode, DateTime nextAirDate, int frequency, int curSeason, int curEpisode, MemoryStream coverStream, SelectedCollection collection, string moveDestPath)
        //{
            
            
            
        //    if(coverStream == null)
        //    {
        //        serieCollection.addSerie(new Serie(titel,season,episode,nextAirDate,frequency,null,curSeason,curEpisode,moveDestPath),SelectedCollection.Active);
        //    }
        //    else
        //    {
        //        string coverPath = GeneralVars.DEFAULT_COVER_FOLDER_PATH + new string(titel.ToCharArray().Where(c => !char.IsPunctuation(c)).ToArray()) + ".jpg";

        //        //@todo might need to check if it alwayse is an JPG
        //        IO_Covers.saveCover(coverPath, coverStream); 
        //        serieCollection.addSerie(new Serie(titel,season,episode,nextAirDate,frequency,coverPath,curSeason,curEpisode,moveDestPath),collection);
        //    }
            
        //}
        

        /// <summary>
        /// remove serie 
        /// </summary>
        /// <param name="titel">serie title</param>
        public void removeSerie(string titel, SelectedCollection collection)
        {
            if(serieCollection.removeSerie(titel,collection))
            {
                try
                {
                    IO_Covers.removeCover("Covers/" + new string(titel.ToCharArray().Where(c => !char.IsPunctuation(c)).ToArray()) + ".jpg");
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                }
            }
        }

        /// <summary>
        /// update serie from active serie list
        /// </summary>
        /// <param name="uSerie">new serie object</param>
        public void updateSerie(Serie uSerie, SelectedCollection collection, string oldTitle = null, Image cover = null)
        {
            if(cover != null)
            {
                string oldPath = uSerie.CoverPath;
                string coverPath = GeneralVars.DEFAULT_COVER_FOLDER_PATH + new string(uSerie.Titel.ToCharArray().Where(c => !char.IsPunctuation(c)).ToArray()) + ".jpg";
                if (File.Exists(coverPath))
                {
                    oldPath = coverPath;
                    Random random = new Random();
                    coverPath = GeneralVars.DEFAULT_COVER_FOLDER_PATH + new string(uSerie.Titel.ToCharArray().Where(c => !char.IsPunctuation(c)).ToArray()) + random.Next(0,10000)+ ".jpg";
                }
                IO_Covers.saveCover(coverPath, cover);
               
                oldCoverPaths.Add(oldPath); //add old cover path to array, they will be removed at next startup.
                uSerie.CoverPath = coverPath;
            }
            serieCollection.updateSerie(uSerie,oldTitle,collection);
        }

        /// <summary>
        /// gets the remember message
        /// </summary>
        /// <returns></returns>
        public string getRememberMessage()
        {
            
            List<Serie> temp = serieCollection.getAiredSeries(IO_Settings.GetSettings().WarningDelay);
            StringBuilder sb = new StringBuilder();

            if(temp.Count != 0)
            {
                foreach (Serie serie in temp)
                {
                    sb.AppendLine(serie.Titel + ":   Season: " + serie.CurSeason + "  Episode: " + serie.CurEpisode);
                }

                return sb.ToString();
            }
            else
            {
                return null;
            }
        }

        #endregion
        
        
        #region general

        public void moveSerieActiveToArchived(Serie serie)
        {
            serieCollection.moveSerieActiveToArchived(serie);
        }

        public void moveSerieArchivedToActive(Serie serie)
        {
            serieCollection.moveSerieArchivedToActive(serie);
        }

        public MemoryStream getCoverPic(string title)
        {
            string coverUrl = IO_IMDB.getPic(title);

            if (!coverUrl.Equals("NULL"))
            {
                return IO_IMDB.DownloadCover(coverUrl);
            }
            else
            {
                return null;
            }
        }

        public void removeOldCovers()
        {
            oldCoverPaths = IO_Covers.getOldCoversPathsFile(OLD_COVER_PATH);

            if(oldCoverPaths.Count != 0)
            {
                for (int i = oldCoverPaths.Count-1; i >= 0; i--)
                {
                    if (File.Exists(oldCoverPaths[i]))
                    {
                        File.Delete(oldCoverPaths[i]);
                        oldCoverPaths.RemoveAt(i);
                    }
                }
            }
        }

       

        #endregion

   }
}
